﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using XXF.Api;
using XXF.Attributes;
using XXF.Db;
using XXF.Extensions;
using XXF.ProjectTool;

namespace XXF.Base
{
    /// <summary>
    /// 基类api控制器
    /// </summary>
    public class BaseApiController : BaseCommonController
    {
        public BaseApiController()
        {
            //GoToOpenApi();
        }
        /// <summary>
        /// 拦截执行前方法
        /// </summary>
        /// <param name="requestContext"></param>
        /// <param name="callback"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        protected override IAsyncResult BeginExecute(System.Web.Routing.RequestContext requestContext, AsyncCallback callback, object state)
        {
            GoToOpenApi(requestContext);
            return base.BeginExecute(requestContext, callback, state);
        }

        /// <summary>
        /// OpenApi属性自动公开api
        /// </summary>
        /// <param name="requestContext"></param>
        public void GoToOpenApi(System.Web.Routing.RequestContext requestContext)
        {
            string controller = requestContext.RouteData.Values["controller"] as string;
            string action = requestContext.RouteData.Values["action"] as string;
            var method = this.GetType().GetMethod(action, BindingFlags.Public | BindingFlags.IgnoreCase);
            if (method == null)
            {
                string namespacestr = this.GetType().Namespace.Replace(".Controllers", "");
                //仅支持dal层的数据查找（相同类名）
                var obj = Assembly.GetAssembly(this.GetType()).CreateInstance(namespacestr + ".dal." + controller, true);
                if (obj != null)
                {
                    var methodfind = obj.GetType().GetMethod(action, BindingFlags.Instance | BindingFlags.Public
                        | BindingFlags.IgnoreCase);
                    //查找方法 及是否包含openapi特性
                    //var attr = ;
                    if (methodfind == null || methodfind.GetCustomAttributes(typeof(OpenApiAttribute), false) == null)
                    {
                        return;
                    }
                    this.Visit((c) =>
                    {
                        //方法填充参数
                        List<object> ps = new List<object>();
                        foreach (var p in methodfind.GetParameters())
                        {
                            //忽略数据库连接参数
                            if (p.GetType() == typeof(DbConn))
                            {
                                ps.Add(c);
                                continue;
                            }
                            //填充名称相同的参数
                            bool findparam = false;
                            foreach (var p2 in requestContext.HttpContext.Request.RequestParams())
                            {
                                if (p.Name.ToLower() == p2.ToLower())
                                {
                                    findparam = true;
                                    ps.Add(requestContext.HttpContext.Request.RequestParamValue(p2));
                                    continue;
                                }
                            }
                            if (findparam == false)
                            {
                                //填充默认值
                                //if (p.d)
                                //{
                                ps.Add(p.DefaultValue);
                                //}
                            }
                        }
                        var r = methodfind.Invoke(obj, ps.ToArray());
                        //输出json
                        System.Web.HttpContext.Current.Response.Write(r);
                        System.Web.HttpContext.Current.Response.End();
                        return null;
                    });
                }
            }
        }

        /// <summary>
        /// api访问回调封装
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        public ActionResult Visit(Func<Db.DbConn, object> action)
        {
            return ControllerHelper.Visit(action);
        }



    }
}
